#include "camera.h"

camera::camera(QObject *parent) :
    QObject(parent)
{
    m_ServerConnected = false;///???
    n_ServerConnected = false;

    this->tcp_socket_short = new QTcpSocket(this);
    connect(this->tcp_socket_short,SIGNAL(readyRead()),this,SLOT(socket_short_rec()));
    connect(tcp_socket_short, SIGNAL(connected()), this, SLOT(socket_short_connected()));
    connect(tcp_socket_short, SIGNAL(disconnected()), this, SLOT(socket_short_desconnected()));
    connect(tcp_socket_short, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayshortError(QAbstractSocket::SocketError)));

    //car number link
    this->tcp_socket_long = new QTcpSocket(this);
    connect(tcp_socket_long,SIGNAL(readyRead()),this,SLOT(socket_long_rec()));
    connect(tcp_socket_long, SIGNAL(connected()), this, SLOT(socket_long_connected()));
    connect(tcp_socket_long, SIGNAL(disconnected()), this, SLOT(socket_long_desconnected()));
    connect(tcp_socket_long, SIGNAL(error(QAbstractSoc
                                          ket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));


    link_Timer = new QTimer();
    connect(link_Timer,SIGNAL(timeout()),SLOT(linkTimerOver())); ///先关闭长链接
    connect(link_Timer,SIGNAL(timeout()),SLOT(socket_long_send()));///然后送发请求车牌识别信息包头/////???
    this->link_Timer->start(LINK_TIME);
}
void camera::linkTimerOver()
{
  this->socket_link(this->camerarIp);
}
void camera::socket_link(QString ip)
{
    //short link
    this->camerarIp = ip;
    if(m_ServerConnected)
    {
      return;
    }
    if(tcp_socket_long->state()== QAbstractSocket::ConnectedState)
    {
    tcp_socket_long->abort();
    tcp_socket_long->close();
    tcp_socket_long->disconnectFromHost();
    this->packHeader_long.clear();
    }
    tcp_socket_long->connectToHost(this->camerarIp,8200);
}

void camera::socket_long_send()///当客户端需要请求车牌识别结果时，需要向IPC设备8200端口号发起连接，并发送u32Size为32，u32Type为 0x1007的数据包。
{
    //qDebug()<<this->camerarIp<<m_ServerConnected;
    if(!m_ServerConnected)
    {
      return;
    }
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = 0x1007;
    this->packHeader_long.clear();
    this->picBuffer_long.clear();
    this->tcp_socket_long->write(pack.buffer,sizeof(pack));
}

void camera::longsocket_in(QString ip)
{
    //qDebug()<<this->camerarIp<<tcp_socket_long->state();
    if(tcp_socket_long->state()== QAbstractSocket::ConnectedState)
    {
        //qDebug()<<this->camerarIp<<"duan";
        tcp_socket_long->abort();
        tcp_socket_long->close();
        tcp_socket_long->disconnectFromHost();
        this->packHeader_long.clear();
    }
    this->camerarIp = ip;
    tcp_socket_long->connectToHost(this->camerarIp,8200);
  //qDebug()<<this->camerarIp<<"lian";
 }

void camera::socket_short_request(int request)
{
    this->request_type = request;
    if(tcp_socket_short->state()== QAbstractSocket::ConnectedState)
    {
        tcp_socket_short->abort();
        tcp_socket_short->close();
        tcp_socket_short->disconnectFromHost();
    }
    this->tcp_socket_short->connectToHost(this->camerarIp,8117);
}

void camera::socket_short_request_open(int request)
{
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = request;
    if(pack.data.u32Type == REQUEST_RS485)
    {
        pack.data.u32Size += this->picBuffer_short.length();
    }
    this->packHeader_short.clear();
    packHeader_short.append(pack.buffer,sizeof(pack));
    packHeader_short.append(this->picBuffer_short);
    //tcp_socket_short->write(this->packHeader_short);

    if((this->short_fd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
        qDebug()<<"creat short_fd error";
    }
    this->s_addr.sin_family=AF_INET;
    this->s_addr.sin_port=htons(8117);
    this->s_addr.sin_addr.s_addr=inet_addr(this->camerarIp.toLocal8Bit().data());
    int s_len=sizeof(s_addr);
    if(::connect(this->short_fd,(struct sockaddr*)&s_addr,s_len)<0)
    {
        qDebug()<<"connect error";
        return ;
    }
    int n=::write(short_fd,packHeader_short.data(),packHeader_short.length());
    usleep(180000);
    ::close(this->short_fd);
    this->packHeader_short.clear();
    this->picBuffer_short.clear();
  //this->tcp_socket_short->connectToHost(this->camerarIp,8117);
}

void camera::socket_short_connected() ///连接上回调函数
{
    n_ServerConnected = true;
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = this->request_type;
    if(pack.data.u32Type == REQUEST_RS485)
    {
        pack.data.u32Size += this->picBuffer_short.length();
    }
    this->packHeader_short.clear();
    packHeader_short.append(pack.buffer,sizeof(pack));
    packHeader_short.append(this->picBuffer_short);
    tcp_socket_short->write(this->packHeader_short);
    this->packHeader_short.clear();
    this->picBuffer_short.clear();
    //qDebug() << "send request:" << this->request_type;
}
void camera::socket_short_desconnected()
{
    n_ServerConnected = false;
    pack_head_t pack;
    tcp_socket_short->close();
    memcpy(pack.buffer,this->packHeader_short.data(),sizeof(pack));
   // qDebug() << "short pack len:" <<  pack.data.u32Size;
 // qDebug() << "short pack type:" << hex << pack.data.u32Type;
    if(pack.data.u32Type == REQUEST_PHOTO_RES)
    {
        //qDebug() << "picture size:" << this->picBuffer_short.length();
       /*QFile myfile("D:/photo.jpg");
        myfile.open(QIODevice::WriteOnly);
        myfile.write(this->picBuffer_short);
        myfile.close();*/
        QPixmap aa;
        aa.loadFromData(this->picBuffer_short,0,Qt::AutoColor);
        emit carNumberRecEnd("",&aa);
    }
    this->packHeader_short.clear();
    this->picBuffer_short.clear();
}
void camera::socket_short_rec()
{
    if(this->packHeader_short.length() == 0)
    {
        this->packHeader_short = this->tcp_socket_short->read(32);
        this->picBuffer_short.clear();
    }
    this->picBuffer_short.append(tcp_socket_short->readAll());
    //qDebug() <<"packHeader_short:" << this->picBuffer_short.length();
}
void camera::socket_short_syncTime()
{
    QByteArray sendBuffer;
    yb_led_syncTime(&sendBuffer);
    qDebug()<<"synctime";
    this->socket_short_send(sendBuffer);
}

void camera::socket_short_send(QByteArray buf)///给摄像机发送 语音 屏幕信息 会封摄像机头部信息
{
    pack_head_t pack;
    QByteArray sendArray;
    ///***************************************
    //     添加摄像机数据包包头
    //***************************************
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = REQUEST_RS485;
    pack.data.u32Size += buf.length();
    sendArray.append(pack.buffer,sizeof(pack));
    //
    sendArray.append(buf);
    if((this->short_fd=socket(AF_INET,SOCK_STREAM,0))<0)
           qDebug()<<"creat short_fd error";
    this->s_addr.sin_family=AF_INET;
    this->s_addr.sin_port=htons(8117);
    this->s_addr.sin_addr.s_addr=inet_addr(this->camerarIp.toLocal8Bit().data());
    int s_len=sizeof(s_addr);
    if(::connect(this->short_fd,(struct sockaddr*)&s_addr,s_len)<0)
    {
        qDebug()<<"connect error";
        return ;
    }
    int n=::write(short_fd,sendArray.data(),sendArray.length());
    //int n=::write(short_fd,"hello",strlen("hello"));
    //qDebug()<<QString("send %1 byte").arg(n);
    usleep(180000);
    ::close(this->short_fd);
}
void camera::socket_short_display(displayData_t *info) ///次函数会封装 语音  屏幕的头部信息 然后通过socket_short_send添加摄像机头部信息发给摄像机，摄像机转发，语音，屏幕
{
        qDebug()<<"socket_short_display";
        QByteArray sendArray;
        //发送语音
        QTextCodec * gb2312 = QTextCodec::codecForName("GB2312");
        QByteArray temp=gb2312->fromUnicode(info->audioStr);
        sendArray.append(0xAA);
        sendArray.append(0x55);
        sendArray.append(0xAA);
        sendArray.append(0x66);
        if(info->audioStr == "车牌识别  一车一杆  减速慢行")
        {
            sendArray.append(0x01);
        }
        else
        {
            sendArray.append(0x02);
        }
        sendArray.append((char)(temp.length()));
        sendArray.append(temp);
        char check = (char)(temp.length());
        foreach(char byte,temp)
        {
            check ^= byte;
        }
        sendArray.append(check);
        this->socket_short_send(sendArray);
      //  qDebug()<<"socket_short_display---voice";
        //发送显示屏
        for(int i=1;i<=4;i++)
        {
            if(!info->DispelayStr[i-1].isEmpty())
            {
                sendArray.clear();
                yb_led_create_park(i,BX_5K1,info->DispelayStr[i-1],&sendArray);
                this->socket_short_send(sendArray);
            }
        }
        //qDebug()<<"socket_short_display---video";
}

void camera::socket_long_connected()///当客户端需要请求车牌识别结果时，需要向IPC设备8200端口号发起连接，并发送u32Size为32，u32Type为 0x1007的数据包。
{
    m_ServerConnected = true;
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = 0x1007;
    this->packHeader_long.clear();
    this->picBuffer_long.clear();
    this->tcp_socket_long->write(pack.buffer,sizeof(pack));
    qDebug() << "socket long connected";
}

void camera::socket_long_desconnected()
{
    m_ServerConnected = false;
    this->tcp_socket_long->close();
    qDebug() << "socket long desconnected!";
}

void camera::displayError(QAbstractSocket::SocketError)
{
    m_ServerConnected = false;
   //qDebug()<<this->camerarIp<<"error123:"<<this->tcp_socket_long->errorString();
}

void camera::displayshortError(QAbstractSocket::SocketError)
{
    n_ServerConnected = false;
   //qDebug()<<this->camerarIp<<"error123:"<<this->tcp_socket_short->errorString();
}

void camera::socket_long_rec()
{
    curentTime= QDateTime::currentDateTime();
    emit sendMsg(curentTime);
    pack_head_t *pack;
    this->link_Timer->stop();
    this->link_Timer->start(LINK_TIME);
    if(this->packHeader_long.length()==0)
    {
        this->packHeader_long = this->tcp_socket_long->read(32);
        pack = (pack_head_t *)this->packHeader_long.data();
        //qDebug() << "long rec len:" << this->packHeader_long.length();
        //qDebug() << "long size is:" << pack->data.u32Size;
        //qDebug() << "long type is:" << hex <<pack->data.u32Type;
        if(pack->data.u32Type != REQUEST_NUMBER_RES)                         ////ICE_EVENT_TYPE_VLPR_EVENT = 0x2002	车牌数据上报
        {
            this->packHeader_long.clear();
        }
        this->picBuffer_long.clear();
    }
    this->picBuffer_long.append(this->tcp_socket_long->readAll());
    pack = (pack_head_t *) this->packHeader_long.data();
    if(this->picBuffer_long.length() == (int)(pack->data.u32Size - 32))
    {
        ICE_VDC_PICTRUE_INFO_BUFFER_S *picBuffer = (ICE_VDC_PICTRUE_INFO_BUFFER_S *)this->picBuffer_long.data();
        //qDebug() << "car number:" << picBuffer->stPlateInfo.as8PlateNum;
        // qDebug() << "pic size:" << picBuffer->s32PicDataLen;
        QByteArray buffer;
        buffer.clear();
        buffer.append(picBuffer->as8PictureData,picBuffer->s32PicDataLen);
        QPixmap aa;
        aa.loadFromData(buffer,0,Qt::AutoColor);
        QTextCodec*gb2312=QTextCodec::codecForName("GB2312");
        QString str = gb2312->toUnicode(picBuffer->stPlateInfo.as8PlateNum);
        emit carNumberRecEnd(str,&aa);
        this->packHeader_long.clear();
    }
    else if(this->picBuffer_long.length() > (int)(pack->data.u32Size - 32))
    {
        this->packHeader_long.clear();
    }
}


//void camera::socket_short_request_auto(int request)
//{
//    pack_head_t pack;
//    memset(pack.buffer,0,sizeof(pack));
//    pack.data.u32Size = 32;
//    pack.data.u32Type = request;
//    if(pack.data.u32Type == REQUEST_RS485)
//    {
//        pack.data.u32Size += this->picBuffer_short.length();
//    }
//    this->packHeader_short.clear();
//    packHeader_short.append(pack.buffer,sizeof(pack));
//    packHeader_short.append(this->picBuffer_short);

//    if((this->short_fd=socket(AF_INET,SOCK_STREAM,0))<0)
//    {
//        qDebug()<<"creat short_fd error";
//    }
//    this->s_addr.sin_family=AF_INET;
//    this->s_addr.sin_port=htons(8117);
//    this->s_addr.sin_addr.s_addr=inet_addr(this->camerarIp.toLocal8Bit().data());
//    int s_len=sizeof(s_addr);
//    if(::connect(this->short_fd,(struct sockaddr*)&s_addr,s_len)<0)
//    {
//        qDebug()<<"connect error";
//        return ;
//    }
//    int n=::write(short_fd,packHeader_short.data(),packHeader_short.length());
//    usleep(180000);
//    ::close(this->short_fd);
//    this->packHeader_short.clear();
//    this->picBuffer_short.clear();
// }
